
#include <stdio.h>
#include <stdlib.h> // just for exit !!!
#include <string.h> // strlen

#include "parseur_data.h"



ushort print_me(event_t event, char *str){

	if ( str[ 0 ] == '\n' )
		printf(" %s => END\n", event_name[ event ]);
	else
		printf(" %s => %s", event_name[ event ], str);
	return 0;
}


ushort no_args(event_t event, char *str){

	if ( str[ 0 ] != '\n' && str[ 0 ] != '\0' ){
		printf("ERROR (%c => %d) %s => %s",  str[ 0 ], str[ 0 ], event_name[ event ], str);
		exit( 1 );
	}

	printf(" %s => END\n", event_name[ event ]);
	return 1;
}


//	EVENT_SAY,					// say: 8 Chipper: Salut! Hi!
//	EVENT_SAYTEAM,				// sayteam: 11 Useless: soz
//	EVENT_SAYTELL,				// saytell: 8 9 yumyum: wtf
ushort parse_say(event_t event, char *str){
	char *text, *start = str;
	int speaker = 255, listener = 255;

	speaker	= (ushort)strtoul(str , &str, 10);
	str ++;
	if (event == EVENT_SAYTELL){
		listener= (ushort)strtoul(str , &str, 10);
		str ++;
	}

	while (str[0] != ':' && str[1] != '\0' && str[1] != ' ') {
		str ++;
	}
	str ++;
	str ++;

	text = str;
	while (str[0] != '\n')
		str ++;

	ushort len = (ushort)(str - text );
	text = (char*) calloc(sizeof(char),(size_t)(len + 1) );
	strncpy( text, (str - len) , len );

	if (event == EVENT_SAYTELL)
		printf(" playerid %u to %u : %s",  speaker, listener, text);
	else
		printf(" playerid %u : %s\n",  speaker, text);

	free(text);

	return (ushort)(str - start);
}


ushort hash_arg(event_t event, char *str){
	char key[256],value[256];
	char *start = str;
	while (str[0] == '\\') {
		if (sscanf(str,"\\%255[^\\]\\%255[^\\]", key , value) != 2 ){
			printf("ERROR !!!");
			exit (1);
		}
		printf("\t%s => %s\n", key, value);
		str += 2 + strlen(key) + strlen(value);
	}

	if ( str[ 0 ] != '\n' && str[ 0 ] != '\0' ){
		printf("ERROR (%c => %d) %s => %s",  str[ 0 ], str[ 0 ], event_name[ event ], str);
		exit( 1 );
	}

	return (ushort)(str - start);
}

ushort user_info(event_t event, char *str){
	char key[256],value[256];
	char *start = str;

	printf("|1|=>%s", str);
	ushort id = (ushort)strtoul(start , &str, 10);
	str ++;
	printf("|2|=>%s", str);
	printf("\tTARGET => %d\n", id);

	if (event == EVENT_CLIENTUSERINFOCHANGED){
		if (sscanf(str,"%255[^\\]\\%255[^\\]", key , value) != 2 ){
			printf("ERROR !!!\n");
			exit (1);
		}
		printf("\t%s => %s\n", key, value);
		str += 1 + strlen(key) + strlen(value);
	}

	while (str[0] == '\\') {
		if (sscanf(str,"\\%255[^\\]\\%255[^\\]", key , value) == 1 ){
			// If the value is not set (null, size = 0)
//			printf("ERROR !!! %s %s", key, value);
//			exit (1);
			value[0] = '\0';
		}
		printf("\t%s => %s\n", key, value);
		str += 2 + strlen(key) + strlen(value);
	}

	if ( str[ 0 ] != '\n' && str[ 0 ] != '\0' ){
		printf("ERROR (%c => %d) %s => %s",  str[ 0 ], str[ 0 ], event_name[ event ], str);
		exit( 1 );
	}

	return (ushort)( str - start );
}

ushort kill_arg(event_t event, char *str){
	ushort victim = 255, atacker = 255, weapon = 255;
	char* p_end = str;
	atacker	= (ushort)strtoul(p_end , &p_end, 10);
	p_end ++;
	victim	= (ushort)strtoul(p_end , &p_end, 10);
	p_end ++;
	weapon	= (ushort)strtoul(p_end , &p_end, 10);
	printf(" KILL \n\tvictim : %d \n\tattacker : %d \n\tweapon : %d \n", victim, atacker, weapon);
	while( p_end[0] != '\n' && p_end[0] != '\0' ){
		p_end ++;
	}
	return (ushort)( p_end - str );
}

ushort hit_arg(event_t event, char *str){
	//	fx_parseur_data[EVENT_HIT]					= &hit_arg;	// Hit: 7 6 3 8: MQCD||Nyod hit MQCD|H-Star in the Kevlar => victim atacker zone weapon
	ushort victim = 255, atacker = 255, zone = 255, weapon = 255;
	char* p_end = str;
	victim	= (ushort)strtoul(str , &p_end, 10);
	p_end ++;
	atacker	= (ushort)strtoul(p_end , &p_end, 10);
	p_end ++;
	zone	= (ushort)strtoul(p_end , &p_end, 10);
	p_end ++;
	weapon	= (ushort)strtoul(p_end , &p_end, 10);
	printf(" HIT \n\tvictim : %d \n\tattacker : %d \n\tzone : %d \n\tweapon : %d \n", victim, atacker, zone, weapon);
	while( p_end[0] != '\n' && p_end[0] != '\0' ){
		p_end ++;
	}
	return (ushort)( p_end - str );
}

ushort target_arg(event_t event, char *str){

	if ( str[ 0 ] == '\n' || str[ 0 ] == '\0' ){
		printf("ERROR (%c => %d) %s => %s",  str[ 0 ], str[ 0 ], event_name[ event ], str);
		exit( 1 );
	}

	char *p_end;
	ushort id = (ushort)strtoul(str , &p_end, 10);
	printf(" %s => target : %d\n", event_name[ event ], id );

	ushort r = (ushort)( p_end - str + (event == EVENT_BOMB_DEFUSED) );

	if ( str[ r ] != '\n' && str[ r ] != '\0' ){
		printf("ERROR (%c => %d) %s => %s",  str[ r ], str[ r ], event_name[ event ], str);
		exit( 1 );
	}

	return r;
}


void init_fx_parseur_data(){


	//load default
	for( int i = 0; i < EVENT_MAX ; i++ )
		fx_parseur_data[ i ] = &print_me;

	// change one fx
	fx_parseur_data[EVENT_ASSASSINWINNER_BLUE] = &print_me;


	//==================================//
	// no data
	//==================================//
	fx_parseur_data[EVENT_ASSASSINWINNER_BLUE]	= &no_args;	// AssassinWinner: Red Reached the Flag
	fx_parseur_data[EVENT_ASSASSINWINNER_RED]	= &no_args;	// AssassinWinner: Blue Reached the Flag
	fx_parseur_data[EVENT_EXIT_TIMELIMIT]		= &no_args;	// Exit: Timelimit hit.
	fx_parseur_data[EVENT_EXIT_FRAGLIMIT]		= &no_args;	// Exit: Fraglimit hit.
	fx_parseur_data[EVENT_FLAG_RETURN_BLUE]		= &no_args;	// Flag Return: BLUE
	fx_parseur_data[EVENT_FLAG_RETURN_RED]		= &no_args;	// Flag Return: RED
	fx_parseur_data[EVENT_POP]					= &no_args;	// Pop!
	fx_parseur_data[EVENT_SHUTDOWNGAME]			= &no_args;	// ShutdownGame:
	fx_parseur_data[EVENT_SURVIVORWINNER_DRAW]	= &no_args;	// SurvivorWinner: Draw
	fx_parseur_data[EVENT_SURVIVORWINNER_BLUE]	= &no_args;	// SurvivorWinner: Blue
	fx_parseur_data[EVENT_SURVIVORWINNER_RED]	= &no_args;	// SurvivorWinner: Red
	fx_parseur_data[EVENT_WARMUP]				= &no_args;	// Warmup:
	fx_parseur_data[EVENT_BIG_MIDDLE_LINE]		= &no_args;	// ------------------------------------------------------------

	//==================================//
	// One ushort Arg (player id)
	//==================================//
	fx_parseur_data[EVENT_BOMB_TOSSED]			= &target_arg;	// Bomb was tossed by 6
	fx_parseur_data[EVENT_BOMB_PLANTED]			= &target_arg;	// Bomb was planted by 6
	fx_parseur_data[EVENT_BOMB_DEFUSED]			= &target_arg;	// Bomb was defused by 8!
	fx_parseur_data[EVENT_BOMB_COLLECTED]		= &target_arg;	// Bomb has been collected by 9
	fx_parseur_data[EVENT_BOMBHOLDER]			= &target_arg;	// Bombholder is 6
	fx_parseur_data[EVENT_CLIENTBEGIN]			= &target_arg;	// ClientBegin: 6
	fx_parseur_data[EVENT_CLIENTCONNECT]		= &target_arg;	// ClientConnect: 6
	fx_parseur_data[EVENT_CLIENTDISCONNECT]		= &target_arg;	// ClientDisconnect: 6


	//==================================//
	// Lot of args with anti-slash
	//==================================//
	fx_parseur_data[EVENT_CLIENTUSERINFO]		= &user_info;	//	ClientUserinfo:(.*)$
	fx_parseur_data[EVENT_CLIENTUSERINFOCHANGED]= &user_info;	//	ClientUserinfoChanged:(.*)$
	fx_parseur_data[EVENT_INITGAME]				= &hash_arg;	// InitGame:(.*)$
	fx_parseur_data[EVENT_INITROUND]			= &hash_arg;	// InitRound:(.*)$

	//==================================//
	// Others
	//==================================//
	//	EVENT_FLAG,					// Flag: 7 2: team_CTF_blueflag
	fx_parseur_data[EVENT_HIT]					= &hit_arg;		// Hit: 7 6 3 8: MQCD||Nyod hit MQCD|H-Star in the Kevlar => victim atacker zone weapon
	//	EVENT_ITEM,					// Item: 6 team_CTF_redflag
	fx_parseur_data[EVENT_KILL]					= &kill_arg;	// Kill: 6 6 10: rafiky killed rafiky by MOD_CHANGE_TEAM
	//	EVENT_RED,					// red:10  blue:6
	fx_parseur_data[EVENT_SAY]					= &parse_say;	// say: 8 Chipper: Salut! Hi!
	fx_parseur_data[EVENT_SAYTEAM]				= &parse_say;	// sayteam: 11 Useless: soz
	fx_parseur_data[EVENT_SAYTELL]				= &parse_say;	// saytell: 8 9 yumyum: wtf
	//	EVENT_SCORE,				// score: 137  ping: 50  client: 14 Wataii
	//	EVENT_TELL,					// tell: yumyum to mike: wtf

}

